package com.blog.boot.webapp.utils;

import com.blog.boot.api.admin.vo.FileModel;
import com.blog.boot.webapp.controller.FileController;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class GetFileList {
    public static final String FILETYPE_DIR = "dir";
    public static final String FILETYPE_FILE = "file";
    //遍历某目录下的所有目录
    public static void listDirectoryFile(File dir) throws IOException {
        checkDir(dir);
        //该目录下所有子目录及子文件，返回String数组
		/*String[] fileNames = dir.list();
		for(String fileName :fileNames){
			System.out.println(dir+"\\"+fileName);
		}*/

        //该目录下所有目录及文件，返回file数组
        File[] files = dir.listFiles();
        if( files != null && files.length > 0 ){//如果有下级目录
            for(File file : files){
                if(!file.isDirectory()){//如果不是目录则直接打印出来
                    System.out.println(file.getAbsolutePath());
                }else{//如果是目录，递归调用本方法
                    System.out.println(file.getAbsolutePath());
                    listDirectoryFile(file);
                }
            }
        }
    }


    /***
     * 获取文件目录下所有文件 包含目录
     * @param dir
     * @return
     * @throws IOException
     */
    public static JSONArray getFileListByFile(File dir) throws IOException{
        checkDir(dir);
        JSONArray jsonArrayFile = new JSONArray();
        JSONArray jsonArrayDir = new JSONArray();
        for(File file : dir.listFiles()){

            FileModel fileModel = getFileByObj(file);

            if(fileModel.getFileType().equals(FILETYPE_DIR)){
                jsonArrayDir.add(fileModel);
            }else{
                jsonArrayFile.add(fileModel);
            }

            /*//这里是为让目录在前面
            if(!file.isDirectory()) {
                FileModel fileModel = new FileModel();
                fileModel.setFileName(file.getName());
                fileModel.setFileSize(getPrintSize(file.length()));
                String path = file.getAbsolutePath().replace("\\", "/").split(FileController.CLASSPath)[1];
                if(!"/".equals(path.split("")[0])){
                    path = path + "/";
                }
                fileModel.setFilePath(path);
                fileModel.setFileTime(dataToStringByLong(file.lastModified()));
                fileModel.setFileType("file");
                jsonArrayFile.add(fileModel);
            }else{
                FileModel fileModel = new FileModel();
                fileModel.setFileName(file.getName());
                fileModel.setFileSize(getPrintSize(file.length()));
                fileModel.setFilePath(file.getAbsolutePath().replace("\\","/").split(FileController.CLASSPath)[1]);
                fileModel.setFileTime(dataToStringByLong(file.lastModified()));
                fileModel.setFileType("dir");
                jsonArrayDir.add(fileModel);
            }*/

        }
        jsonArrayDir.addAll(jsonArrayFile);
        return jsonArrayDir;
    }


    /***
     * Long的时间转正常时间
     * @param l
     * @return
     */
    public static String dataToStringByLong(Long l){
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
        return dateFormat.format(new Date(l));
    }
    /***
     * 根据件名获取当前对象目录下的本file对象
     * @param dir
     * @param fileName
     * @return
     */
    public static File getFileByDirPath(File dir,String fileName){
        checkDir(dir);
        for(File file : dir.listFiles()){
            if(!file.isDirectory() && fileName.equals(file.getName())) {
                return file;
            }
        }
        return null;
    }

    public static FileModel getFileByObj(File file){
        FileModel fileModel = new FileModel();
        fileModel.setFileName(file.getName());
        fileModel.setFileSize(getPrintSize(file.length()));
        String path = file.getAbsolutePath().replace("\\", "/").split(FileController.CLASSPATH)[1];
        /*if(!"/".equals(path.split( "")[0])){//判断切割过后的文件开头是否是/开头
            path = "/" + path;
        }*/
        fileModel.setFilePath(path);
        fileModel.setFileType(file.isDirectory()?FILETYPE_DIR:FILETYPE_FILE);
        fileModel.setFileTime(dataToStringByLong(file.lastModified()));
        return fileModel;
    }


    // 递归方式 计算文件的大小
    private static long getTotalSizeOfFilesInDir(final File file) {
        if (file.isFile())
            return file.length();
        final File[] children = file.listFiles();
        long total = 0;
        if (children != null)
            for (final File child : children)
                total += getTotalSizeOfFilesInDir(child);
        return total;
    }

    /**
     * 根据file对象获取文件的文本内容
     * @param file
     * @return
     */
    public static String getContentTextByFile(File file){
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            inputStream = new FileInputStream(file);
            inputStreamReader = new InputStreamReader(inputStream,"utf-8");
            bufferedReader = new BufferedReader(inputStreamReader);
        } catch (Exception e) {
            e.printStackTrace();
        }
        StringBuffer stringBuffer = new StringBuffer();
        char[] bytes = new char[512];
        int size = 0;
        String temp;
        try {
            while ((temp=bufferedReader.readLine())!=null){
                stringBuffer.append(temp+"\n");
            }
            return stringBuffer.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bufferedReader.close();//先用后关 后用先关
                inputStreamReader.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }
    /***
     * 获取文件目录下所有目录 不包含目录
     * @param dir
     * @return
     * @throws IOException
     */
    public static JSONArray getFileListByDir(File dir) throws IOException{
        checkDir(dir);
        JSONArray jsonArray = new JSONArray();

        return jsonArray;
    }

    public static void checkDir(File dir){
        if(!dir.exists()){//dir不存在，抛出异常
            throw new IllegalArgumentException("目录"+dir+"不存在");
        }
        if(!dir.isDirectory()){//dir不是目录抛出异常
            throw new IllegalArgumentException(dir+"不是目录");
        }
    }

    public static double getM(double k){ // 该参数表示kb的值
        double m;
        m = k / 1024.0;
        return m; //返回kb转换之后的M值
    }

    public static String getPrintSize(long size) {
        //如果字节数少于1024，则直接以B为单位，否则先除于1024，后3位因太少无意义
        if (size < 1024) {
            return String.valueOf(size) + "B";
        } else {
            size = size / 1024;
        }
        //如果原字节数除于1024之后，少于1024，则可以直接以KB作为单位
        //因为还没有到达要使用另一个单位的时候
        //接下去以此类推
        if (size < 1024) {
            return String.valueOf(size) + "KB";
        } else {
            size = size / 1024;
        }
        if (size < 1024) {
            //因为如果以MB为单位的话，要保留最后1位小数，
            //因此，把此数乘以100之后再取余
            size = size * 100;
            return String.valueOf((size / 100)) + "."
                    + String.valueOf((size % 100)) + "MB";
        } else {
            //否则如果要以GB为单位的，先除于1024再作同样的处理
            size = size * 100 / 1024;
            return String.valueOf((size / 100)) + "."
                    + String.valueOf((size % 100)) + "G";
        }
    }

    /**
     * 把更新的文件写入文件 做一次备份功能
     * @param file
     * @param fileModel
     */
    public static void upfile(File file,FileModel fileModel){
        String bakFileName = getBakFileName(file);//获取带bak的文件名
        File newfile = new File(bakFileName);//创建新名字的抽象文件
        if(!newfile.exists()){
            try {
                newfile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        writeTxt(newfile,getFileBybByteArr(file));//先将老文件里面的字节放在带有_bak的文件名中 作为备份
        try {
            writeTxt(file,fileModel.getFileContent().getBytes("UTF-8"));//将新文本放在原文件中
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取文件名带bak
     * @param file
     * @return
     */
    public static String getBakFileName(File file){
        String name = file.getName();
        String parent = file.getParent();
        int i = name.lastIndexOf(".");
        String newName = parent+"/"+(name.substring(0, i))+"_bak"+(name.substring(i,name.length()));
        return newName;
    }

    /**
     * 获取文件名后缀
     * @param fileName
     * @return
     */
    public static String getSuffixByFileName(String fileName){
        int i = fileName.lastIndexOf(".");
        return fileName.substring(i,fileName.length());
    }

    public static byte[] getFileBybByteArr(File file){
        byte[] bytes = new byte[0];
        try {
            bytes = toByteArray(new FileInputStream(file));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bytes;
    }

    private static byte[] toByteArray(InputStream in) throws IOException {

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024 * 4];
        int n = 0;
        while ((n = in.read(buffer)) != -1) {
            out.write(buffer, 0, n);
        }
        in.close();
        out.close();
        return out.toByteArray();
    }
    /**
     * 将指定字节写入文件
     * @param file
     * @param bytes
     */
    public static void writeTxt(File file,byte[] bytes){
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            fileOutputStream.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public boolean ReName(String path,String newname) {//文件重命名
        //Scanner scanner=new Scanner(System.in);
        File file=new File(path);
        if(file.exists()) {
            File newfile=new File(file.getParent()+File.separator+newname);//创建新名字的抽象文件
            if(file.renameTo(newfile)) {
                System.out.println("重命名成功！");
                return true;
            }
            else {
                System.out.println("重命名失败！新文件名已存在");
                return false;
            }
        }
        else {
            System.out.println("重命名文件不存在！");
            return false;
        }
    }

    /**
     * 删除文件 与 文件夹
     * @param fileModel
     */
    public static void delFile(FileModel fileModel){
        String filePath = fileModel.getFilePath();
        File file = new File(filePath);
        if(file.exists()){
            if(!file.isDirectory()){//如果是文件 那么直接干掉
                file.delete();
            }else{
                delAllFile(fileModel.getFilePath());
                file.delete();//删除空文件夹
            }
        }
    }


    /***
     * 删除指定文件夹下所有文件
     *
     * @param path 文件夹完整绝对路径
     * @return
     */
    public static  boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件
                delFolder(path + "/" + tempList[i]);// 再删除空文件夹
                flag = true;
            }
        }
        return flag;
    }

    /***
     * 删除文件夹
     *
     * @param folderPath 文件夹完整绝对路径
     */
    public  static void delFolder(String folderPath) {
        try {
            delAllFile(folderPath); // 删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            java.io.File myFilePath = new java.io.File(filePath);
            myFilePath.delete(); // 删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static JSONObject createFile(String fileName,String filePath,String fileType){
        File file = new File(filePath);
        JSONObject jsonObject = new JSONObject();
        String path = "";
        if(file.isDirectory()) {//如果是文件夹那么就要创建的该下
            path = file.getPath();
        }else{
            path = file.getParent();
        }
        File newFile = new File(path+File.separator+fileName);
        if(newFile.exists()){
            jsonObject.put("code","999");
            jsonObject.put("msg","文件或文件夹已存在！");
            return jsonObject;
        }
        try {
            if("0".equals(fileType)){
                newFile.mkdir();
            }else{
                newFile.createNewFile();
            }
            jsonObject.put("code","200");
            jsonObject.put("msg","创建成功！");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return jsonObject;
        /*if(file.isDirectory()){//如果是文件夹那么就要创建的该下*/
        /*}else{
            String parent = file.getParent();
            File filed = new File(parent+File.separator+fileName);
            if(filed.exists()){
                jsonObject.put("code","999");
                jsonObject.put("msg","文件或文件夹已存在！");
                return jsonObject;
            }
            if("0".equals(fileType)){
                filed.mkdir();
            }else{
                try {
                    filed.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            jsonObject.put("code","200");
            jsonObject.put("msg","创建成功！");
        }
        return jsonObject;*/
    }
}
